'use strict';
const fs = require('fs');
const path = require('path');
const exec = require('child_process').exec;
const { fsHelper, zipHepler } = require('./lib/fsHelper')

/** 包名 */
const PACKAGE_NAME = require('../package.json').name;
const config = require('../config.json');
/**基本库的路径 */
const BASELIBPATH = config.baseLibPath;
/**指定忽略的文件 */
const IGNORE_FILE_LIST = config.ignoreFileList;
/**指定忽略的后缀类型 */
const IGNORE_FILE_SUFFIX = config.ignoreFileSuffix;
let onbuildStart = function (options, callback) {
	Editor.log('onbuildStart', fsHelper);
	// let lib = 'D:/Mycode/nodeJsHelper';
	// copyDirSync_R(lib, options.project + '/packages/', null, 'js')
	callback()
}
let onbuildFinished = function (options, callback) {
	Editor.log('mergeStartScene2', options.mergeStartScene)
	let buildPath = options.buildPath;
	let buildResults = options.buildResults;
	Editor.log('/**************开始处理loading页面资源******************')
	if (fs.existsSync(`${options.project}/assets/assetlist.txt`)) {
		let cfgFile = fs.openSync(`${options.project}/assets/assetlist.txt`, 'r');
		let datastr = fs.readFileSync(cfgFile).toString();
		let data = eval(datastr);

		let packAssets = buildResults._packedAssets;

		if (data && data.is_build_ucDemo == true && options.actualPlatform == 'web-mobile') {
			Editor.log('*******************打包uc_Demo****************')
			let ucDemoPath = __dirname + '/uc_demo';
			Editor.log('ucDemoPath', ucDemoPath)
			let dir = fs.readdirSync(ucDemoPath);
			if (dir && dir.length > 0) {
				dir.forEach((v, i) => {
					let filePath = ucDemoPath + '/' + v;
					let dstFilePath = options.dest + '/' + v;
					if (fsHelper.isFile(filePath)) {
						fs.copyFileSync(filePath, dstFilePath)
					} else if (fsHelper.isDirectory(filePath)) {
						fsHelper.copyDirSync_R(filePath, dstFilePath);
					}
				})
			}
			let zipName = options.projectName + '.zip';
			zipHepler.do_gzip(options.dest, options.buildPath + '/' + zipName, (err, count) => {
				if (err) {
					Editor.error('打包失败:', err);
				} else {
					fs.copyFileSync(options.buildPath + '/' + zipName, options.dest + '/' + zipName);
					fs.unlinkSync(options.buildPath + '/' + zipName);
					Editor.error('打包完成:', count);
				}

				callback();
			});
		}
	}

	callback();
}


module.exports = {
	load() {
		Editor.log('unload');
		// Editor.Builder.on('state-changed', onStartChanged);
		// Editor.Builder.on('before-change-files', onBeforeBuildFinish);
		Editor.Builder.on('build-start', onbuildStart);
		Editor.Builder.on('build-finished', onbuildFinished);
	},

	unload() {
		Editor.log('unload');
		// Editor.Builder.removeListener('state-changed', onStartChanged);
		// Editor.Builder.removeListener('before-change-files', onBeforeBuildFinish);
		Editor.Builder.removeListener('build-start', onbuildStart);
		Editor.Builder.removeListener('build-finished', onbuildFinished);
	},




	messages: {
		/**
		 * 编辑器选中事件回调
		 * @param {Electron.IpcMainEvent} event 
		 * @param {string} type 类型
		 * @param {string[]} uuids uuids
		 */
		// 'selection:selected'(event, type, uuids) {
		// 	// Editor.log(event)
		// 	// Editor.log(type)
		// 	// Editor.log(uuids)
		// 	if (type == 'node') {
		// 		for (let uuid of uuids) {
		// 			// 通过管道把节点的信息传给panel
		// 			// Editor.Ipc.sendToPanel('scene', 'scene:query-node-info', uuid, 'cc.Node', (error, node) => {
		// 			Editor.Ipc.sendToPanel('scene', 'scene:query-hierarchy', uuid, 'cc.Node', (error, sceneID, hierarchy) => {
		// 				Editor.Ipc.sendToPanel('scene', 'scene:query-node', uuid, 'cc.Node', (error, node) => {
		// 					if (error)
		// 						return Editor.error(error);

		// 					// Editor.log('sceneID', sceneID);
		// 					// Editor.log('hierarchy', hierarchy[1].children);
		// 					// Editor.log(JSON.parse(node).value.position.value);
		// 				});
		// 			});
		// 		}
		// 		// Editor.log('data:', data);
		// 		// // 从panel获取格式
		// 		// Editor.Ipc.sendToPanel('build_worker', 'test', data, 3000);
		// 	}
		// },
		// 打开窗口
		'open'() {
			Editor.Panel.open('build_worker');
		},
		// 只更新js文件
		'updateJs'(event) {
			let paths = config.scriptPath;
			updateGameBase(BASELIBPATH, paths);
			// Editor.assetdb.refresh('db://assets');
		},
		// 更新所有（包括图片）
		'updateAll'(event) {
			let paths = config.scriptPath.concat(config.resourcesPath);
			updateGameBase(BASELIBPATH, paths);
			// Editor.assetdb.refresh('db://assets');
		},
		/** 更新ccc框架*/
		'updateCCCFramework'(event) {
			let basePath = 'E:/MyCode/2d/shaderTest/';
			// 替换js
			updateGameBase(basePath, ['assets/script/cccFramework/']);
			// Editor.assetdb.refresh('db://assets');
		},
		'openProjWithCode'() {
			Editor.log('openProjWithCode', Editor.Project.path);
			let cmd = `code ${Editor.Project.path}`;
			execCmd(cmd);
		},
		'explorerBuild'() {
			Editor.log('explorerBuild', Editor.Project.path);
			let cmd = `explorer ${Editor.Project.path}\\build`;
			execCmd(cmd);
		},
		// 打开窗口
		'codeServer'() {
			// Editor.Scene.callSceneScript('build_worker', 'testModule', function (err, length) {
			// 	// Editor.log(`get-canvas-children callback : length - ${length}`);
			// });
			Editor.log('openProjWithCode', Editor.Project.path);
			let cmd = `code ${path.dirname(Editor.Project.path)}\\server`;
			execCmd(cmd);
		},
		'startServer'() {
			Editor.log('startServer');
			let cmd = `start ts-node ${path.dirname(Editor.Project.path)}\\server\\GameServer.ts`;
			Editor.log('startServer', cmd);
			execCmd(cmd);
		},
		'exportAudioList'() {
			Editor.log('exportAudioList');
			let exportAudio = require('./lib/exportAudio')
			exportAudio.start()
		}
	},
};
function execCmd(cmd) {
	exec(cmd, function (error, stdout, stderr) {
		// 获取命令执行的输出
		Editor.log('error', error);
		Editor.log('stdout', stdout);
		Editor.log('stderr', stderr);
	})
}



let updateResCount = 0, updateJsCount = 0, updateAllCount = 0, ignoreFileCount = 0;
let updateResList = [], updateJsList = [], updateAllList = [], ignoreFileList = [];
let isUpdating = false;

/**
 * 更新文件
 * @param {*} fromPath 
 * @param {*} paths 
 */
function updateGameBase(fromPath, paths) {
	let platformTempPath = Editor.Project.path + '/platformTemp/';
	let utilPath = Editor.Project.path + '/assets/script/util/';
	Editor.log('platformTempPath', platformTempPath)
	Editor.log('utilPath', utilPath)
	// Editor.log('fs.existsSync(platformTempPath)', fs.statSync(platformTempPath).isDirectory())

	if (fs.existsSync(platformTempPath) && fs.statSync(platformTempPath).isDirectory()) {
		let list = fs.readdirSync(platformTempPath)
		Editor.log('list', list)
		list.forEach(v => {
			let filePath = platformTempPath + v;
			let destPath = utilPath + v;
			if (fs.statSync(filePath).isFile() && !v.match(/.meta$/) && !fs.existsSync(destPath)) {
				Editor.log('v', v)
				fs.copyFileSync(filePath, destPath)
			}
		})
	}

	// 初始化更新个数
	updateResCount = 0, updateJsCount = 0, updateAllCount = 0, ignoreFileCount = 0;
	updateResList = [], updateJsList = [], updateAllList = [], ignoreFileList = [];
	// 工程路径
	let projectPath = Editor.Project.path + '/';
	// gamebase路径
	let gameBasePath = fromPath || BASELIBPATH;
	// Editor.log('options', Editor.Project.path);
	Editor.log('gameBasePath', gameBasePath);
	// Editor.log('projectPath', projectPath);

	// 递归更新文件
	function updateFile_R(curPath) {
		curPath = curPath.split('/').filter(v => {
			return !!v
		}).join('/');
		let base_path = gameBasePath + curPath;
		let pro_path = projectPath + curPath;
		Editor.log('updateFile_R ===> 1', curPath);
		// 遍历这些文件名，如果本地也存在同样的底层的文件，就直接替换
		let ignore_file_suffix = IGNORE_FILE_SUFFIX.concat();
		ignore_file_suffix = ignore_file_suffix.join('|');
		let rgx = new RegExp(`(${ignore_file_suffix})`);
		if (!ignore_file_suffix) {
			rgx = '//';
		}
		let file = path.basename(curPath)
		Editor.log('updateFile_R ===> 1.1', curPath);
		if (IGNORE_FILE_LIST.includes(curPath) || curPath.match(rgx)) {
			ignoreFileCount++;
			Editor.log('sssssssssssss', curPath)
			ignoreFileList.push(curPath);
			return
		}
		Editor.log('updateFile_R ===> 1.2', curPath);
		if (curPath.match(/.meta$/)) {
			return;
		}
		Editor.log('updateFile_R ===> 1.3', curPath, IGNORE_FILE_LIST, rgx);
		// gamebase文件夹有并且当前工程文件夹也有才复制
		if (fs.existsSync(base_path) && fs.existsSync(pro_path)) {
			Editor.log('updateFile_R ===> 2', base_path);
			// Editor.log('base_path', fs.existsSync(base_path), fs.statSync(base_path).isFile());
			// 都是文件才复制
			if (fs.statSync(base_path).isFile() && fs.statSync(pro_path).isFile()) {
				Editor.log('updateFile_R ===> 3');
				// Editor.warn('base_path2', base_path);
				// if (true || base_stat.ctimeMs > pro_stat.ctimeMs) {
				Editor.warn('替换文件', pro_path);
				fs.copyFileSync(base_path, pro_path);

				Editor.log('updateFile_R ===> 3.1');
				if (curPath.match(/(.js|.ts)/)) {
					updateJsList.push(curPath);
					updateJsCount++;
				} else {
					updateResList.push(curPath);
					updateResCount++;
				}
				Editor.log('updateFile_R ===> 3.2');
				updateAllList.push(curPath);
				updateAllCount++;

				function getDBUrl(realFilePath) {
					let res = realFilePath.replace(Editor.url('db://assets/..'), '');
					res = res.substring(1);
					return `db://${res}`;
				}
				Editor.log('updateFile_R ===> 3.3', pro_path);
				let res_p = getDBUrl(pro_path);
				Editor.assetdb.refresh(res_p)
				// } else {
				// 	Editor.log('已是最新', pro_path);
				// }
				Editor.log('updateFile_R ===> 4');
			} else if (fs.statSync(base_path).isDirectory() && fs.statSync(pro_path).isDirectory()) {

				Editor.log('updateFile_R ===> 5');
				let list = fs.readdirSync(base_path);
				Editor.log(list);
				if (list && list.length) {
					for (let name of list) {
						// 是文件就递归
						updateFile_R(curPath + '/' + name + '/');
					}
					Editor.log('updateFile_R ===> 5.1');
				}
				Editor.log('updateFile_R ===> 6');
			} else {
				// 基本不会走这里，除了文件夹和文件以外的东西才会走这里
				Editor.error('文件类型错误', base_path)
			}
		} else {
			// 不存在路径
			Editor.error('路径不存在', curPath, fs.existsSync(base_path), fs.existsSync(pro_path))
		}
	}

	for (let i of paths) {
		// 递归的替换文件
		updateFile_R(i);
	}

	Editor.log('忽略更新的文件：', ignoreFileCount, '个');
	Editor.log('忽略更新的对文件列表：', ignoreFileList);
	Editor.log('更新脚本： ' + updateJsCount + '个');
	Editor.log('更新脚本列表：', updateJsList);
	Editor.log('更新资源：' + updateResCount + '个');
	Editor.log('更新文件列表：', updateResList);
	Editor.log('更新文件共：' + updateAllCount + '个');
}
